package frames;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.sql.Connection;
import java.sql.SQLException;

import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;

import parameters.ConnectionParams;


/** Implements a basic program menu for the application
 * 
 * @author Konstantin Dobrev
 * @version 1.0
 */
class ProgramMenuBar extends JMenuBar {

	private static final long serialVersionUID = 1L;
	private JMenu fileMenu;
	private JMenuItem createConnItem;
	private JMenuItem useConnItem;
	private JMenuItem closeConnItem;
	private JMenuItem exitItem;
	
	private JMenu sqlMenu;
	private JMenuItem createDBItem;
	private JMenuItem useDBItem;
	
	private Connection dbConn;
	private ProgramFrame mainFrameReff;
	
	/** Constructor for the menu class
	 * 
	 * @param reff references the main program frame in order to
	 * change the database tree
	 * @see ProgramFrame
	 */
	ProgramMenuBar(ProgramFrame reff) {
		super();
		mainFrameReff = reff;
		
		fileMenu = new JMenu("File");
		addFileMenuItems();
		this.add(fileMenu);
	}
	
	/**
	 * Adds the basic menu items to the menu
	 */
	private void addFileMenuItems() {
		createConnItem = new JMenuItem("Create new connection");
		createConnItem.addActionListener(new MenuHandler("Create conn", this));
		fileMenu.add(createConnItem);
		
		useConnItem = new JMenuItem("Use a connection");
		useConnItem.addActionListener(new MenuHandler("Use conn", this));
		fileMenu.add(useConnItem);
		
		closeConnItem = new JMenuItem("Close connection");
		closeConnItem.addActionListener(new MenuHandler("Close conn", this));
		closeConnItem.setEnabled(false);
		fileMenu.add(closeConnItem);
		
		fileMenu.addSeparator();
		exitItem = new JMenuItem("Exit");
		exitItem.addActionListener(new MenuHandler("Exit", this));
		fileMenu.add(exitItem);
	}
	
	/** A getter method for the app's main program frame
	 * 
	 * @return a reference to the main program frame
	 */
	public ProgramFrame getMainRefference() {
		return mainFrameReff;
	}
	
	/** Enables or disables the 'Close connection' option
	 * in the main menu
	 * 
	 * @param val determines the state of the menu option
	 */
	public void setConnectionClosing(boolean val) {
		closeConnItem.setEnabled(val);
	}
	
	/** Stores a Connection value to be used
	 * to manage of databases and tables
	 * 
	 * @param conn contains the reference to the
	 * established connection or null if an active
	 * connection is being closed
	 */
	public void setConnection(Connection conn) {
		dbConn = conn;
	}
	
	
	/** Implements a listener which reacts to the
	 * user's choice of menu options
	 * 
	 * @author Konstantin Dobrev
	 * @version 1.0
	 */
	private class MenuHandler implements ActionListener {

		private String itemName;
		ProgramMenuBar caller;
		
		/** Constructor for the class
		 * 
		 * @param name is used to determine which action should
		 * be invoked
		 * @param reff references the objects which creates the instance of the 
		 * object in order to add components to the main frame
		 */
		MenuHandler(String name, ProgramMenuBar reff) {
			itemName = name;
			caller = reff;
		}
		
		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			switch(itemName) {
			case "Create conn" : getConnectionData(); break;
			case "Use conn" : openConnectionFromFile(); break;
			case "Close conn" : closeConnection(); break;
			case "Exit":  System.exit(0);
			}
		}
		
		/**
		 * Creates a {@link ConnectionFrame} in order to
		 * establish a database connection
		 */
		private void getConnectionData() {
			@SuppressWarnings("unused")
			ConnectionFrame connFr = new ConnectionFrame(new ConnectionParams(), caller);
		}
		
		/**
		 * Uses a .cmng file to get connection data in order
		 * to establish a database connection
		 */
		private void openConnectionFromFile() {
			JFileChooser openChooser = new JFileChooser();
			FileNameExtensionFilter filter = new FileNameExtensionFilter("Connection manager files", "cmng");
			openChooser.setFileFilter(filter);
			int selected = openChooser.showOpenDialog(fileMenu);
			if(selected == 0) {
				File openedFile = openChooser.getSelectedFile();
				ConnectionParams inputParams = null;
				try {
					FileInputStream inputStream = new FileInputStream(openedFile);
					ObjectInputStream inputObject = new ObjectInputStream(inputStream);
					inputParams = (ConnectionParams) inputObject.readObject();
				}
				catch(FileNotFoundException ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage());
					return;
				}
				catch(ClassNotFoundException ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage());
					return;
				}
				catch(IOException ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage());
					return;
				}
				
				ConnectionFrame connFrame = new ConnectionFrame(inputParams, caller);
				connFrame.setFields();
			}
		}
		
		/** Closes an active database connection
		 * 
		 * @exception SQLException
		 */
		private void closeConnection() {
			try {
				dbConn.close();
				closeConnItem.setEnabled(false);
				mainFrameReff.getDbTree().removeConnDatabases();
			}
			catch (SQLException ex) {
				JOptionPane.showMessageDialog(null, ex.getMessage());
			}
			
		}
		
	}

	

}
